home *** CD-ROM | disk | FTP | other *** search
/ Aminet 43 / Aminet 43 (2001)(GTI - Schatztruhe)[!][Jun 2001].iso / Aminet / game / think / Connect4.lha / Connect4 / source / graphics_support.c < prev    next >
C/C++ Source or Header  |  2001-03-28  |  14KB  |  404 lines

  1. #include "graphics_support.h"
  2. #include <clib/graphics_protos.h>
  3. #include <libraries/iffparse.h>
  4. #include <datatypes/pictureclass.h>
  5. #include <clib/iffparse_protos.h>
  6. #include <stdio.h>
  7.  
  8.  
  9. /*
  10. ** INPUTS:
  11. **          bitmap      = pointer to a bitmap (the bitmap contents will be altered)
  12. **          cm          = pointer to ColorMap of the viewport
  13. **          palette     = pointer to an array of RGB values the bitmap would like to use
  14. **          pens        = pointer to an array of storage for (hopefully) allocated pens
  15. **                        NB: all elements of pens array must be set to 0, prior to calling this function!
  16. **          num_pens    = the size of the array (how many pens it can hold)
  17. **
  18. ** RESULT:
  19. **          None
  20. **
  21. ** NOTES:
  22. **          This call must be matched with a call to freeallocatedpens()
  23. */
  24. void remapbitmap (struct BitMap *bitmap, struct ColorMap *cm, ULONG *palette, struct pen *pens, UWORD num_pens)
  25. {
  26.     ULONG R, G, B;
  27.     UBYTE cmap_index[8];    // each pixel ends up with its cmap index val in cmap[pixel]
  28.     WORD i;
  29.     UWORD row, byteinrow;
  30.     ULONG offset=0;
  31.  
  32.     for (row=0; row<bitmap->Rows; row++)
  33.     {
  34.         for (byteinrow=0; byteinrow<bitmap->BytesPerRow; byteinrow++)
  35.         {
  36.             #ifdef GRAPHICS_SUPPORT_DEBUG
  37.             printf("offset:%d\n", offset);
  38.             #endif
  39.  
  40.             // Read in 8 pixels down through the relevant bitplanes
  41.             {
  42.                 int plane_shift;
  43.                 int buffer[8];
  44.  
  45.                 // Erase contents of cmap_index and buffer
  46.                 for (i=0; i<8; i++)
  47.                 {
  48.                     cmap_index[i]=0;
  49.                     buffer[i]=0;
  50.                 }
  51.  
  52.                 #ifdef GRAPHICS_SUPPORT_DEBUG
  53.                 printf("Reading plane data\n");
  54.                 #endif
  55.                 // Plane[0] is least significant plane!
  56.                 plane_shift=bitmap->Depth-1;
  57.                 for (i=bitmap->Depth-1; i>=0; i--)
  58.                 {
  59.                     buffer[i]=*(bitmap->Planes[i]+offset);
  60.                     cmap_index[0]=((UBYTE)(((buffer[i] & 128) >> 7) << plane_shift)) | cmap_index[0];
  61.                     cmap_index[1]=((UBYTE)(((buffer[i] & 64)  >> 6) << plane_shift)) | cmap_index[1];
  62.                     cmap_index[2]=((UBYTE)(((buffer[i] & 32)  >> 5) << plane_shift)) | cmap_index[2];
  63.                     cmap_index[3]=((UBYTE)(((buffer[i] & 16)  >> 4) << plane_shift)) | cmap_index[3];
  64.                     cmap_index[4]=((UBYTE)(((buffer[i] & 8)   >> 3) << plane_shift)) | cmap_index[4];
  65.                     cmap_index[5]=((UBYTE)(((buffer[i] & 4)   >> 2) << plane_shift)) | cmap_index[5];
  66.                     cmap_index[6]=((UBYTE)(((buffer[i] & 2)   >> 1) << plane_shift)) | cmap_index[6];
  67.                     cmap_index[7]=((UBYTE)(((buffer[i] & 1)       ) << plane_shift)) | cmap_index[7];
  68.                     plane_shift--;
  69.                     #ifdef GRAPHICS_SUPPORT_DEBUG
  70.                     printf("buffer[%d]:%4.d   cmap0:%d   cmap1:%d   cmap2:%d   cmap3:%d   cmap4:%d   cmap5:%d   cmap6:%d   cmap7:%d\n",
  71.                             i, buffer[i], cmap_index[0], cmap_index[1], cmap_index[2], cmap_index[3], cmap_index[4], cmap_index[5], cmap_index[6], cmap_index[7]);
  72.                     #endif
  73.                 }
  74.             }
  75.  
  76.             #ifdef GRAPHICS_SUPPORT_DEBUG
  77.             printf("\n");
  78.             #endif
  79.  
  80.             // Allocate any pens we need
  81.             for (i=0; i<8; i++) // Test each pixel
  82.             {
  83.                 if (cmap_index[i]!=0)   // Ignore colour 0, which should be a transparent background
  84.                 {
  85.                     int index=3*cmap_index[i];
  86.  
  87.                     R=palette[index];
  88.                     G=palette[index+1];
  89.                     B=palette[index+2];
  90.                     #ifdef GRAPHICS_SUPPORT_DEBUG
  91.                     printf("R=%x  G=%x  B=%x\n", R, G, B);
  92.                     #endif
  93.  
  94.                     if (!alreadyallocated(R, G, B, pens, num_pens))
  95.                     {
  96.                         WORD freepen;
  97.                         if ((freepen=findfreepen(pens, num_pens))!=-1)
  98.                         {
  99.                             if ((pens[freepen].number=ObtainBestPen(cm, R, G, B, OBP_Precision, PRECISION_IMAGE, TAG_DONE))!=-1)
  100.                             {
  101.                                 pens[freepen].red=R;
  102.                                 pens[freepen].green=G;
  103.                                 pens[freepen].blue=B;
  104.                             }
  105.                         }
  106.                     }
  107.                 }
  108.             }
  109.  
  110.             // Give every pixel that needs it its new pen value
  111.             #ifdef GRAPHICS_SUPPORT_DEBUG
  112.             printf("Reassigning pixel pen values\n");
  113.             #endif
  114.             for (i=0; i<8; i++)
  115.             {
  116.                 if (cmap_index[i]!=0)   // Ignore colour 0, which should be a transparent background
  117.                 {
  118.                     WORD gotpen;
  119.  
  120.                     R=palette[3*cmap_index[i]];
  121.                     G=palette[3*cmap_index[i]+1];
  122.                     B=palette[3*cmap_index[i]+2];
  123.  
  124.                     if ((gotpen=findallocatedpen(R, G, B, pens, num_pens))!=-1)
  125.                     {
  126.                         cmap_index[i]=(UBYTE)(pens[gotpen].number);
  127.                         #ifdef GRAPHICS_SUPPORT_DEBUG
  128.                         printf("gotpen:%4.d  pennum=%4.d  cmap[%d]:%d\n", gotpen, pens[gotpen].number, i, cmap_index[i]);
  129.                         #endif
  130.                     }
  131.                 }
  132.                 #ifdef GRAPHICS_SUPPORT_DEBUG
  133.                 else
  134.                     printf("Skipped colour 0\n");
  135.                 #endif
  136.             }
  137.  
  138.             #ifdef GRAPHICS_SUPPORT_DEBUG
  139.             print_pens(pens, num_pens);
  140.             printf("\n");
  141.             #endif
  142.  
  143.             // Write 8 pixels back into bitmap with new cmap index values for current
  144.             // viewport's struct ColorMap
  145.             #ifdef GRAPHICS_SUPPORT_DEBUG
  146.             printf("Writing plane data\n");
  147.             #endif
  148.             {
  149.                 UBYTE buffer;
  150.                 int bitmask=1;
  151.                 int shift=0;
  152.  
  153.                 for (i=bitmap->Depth-1; i>0; i--)
  154.                     bitmask=bitmask*2;
  155.  
  156.                 // Plane[0] is least significant plane!
  157.                 for (i=bitmap->Depth-1; i>=0; i--)
  158.                 {
  159.                     buffer=   ((cmap_index[0] & bitmask)<<shift)
  160.                             | ((cmap_index[1] & bitmask)<<shift)>>1
  161.                             | ((cmap_index[2] & bitmask)<<shift)>>2
  162.                             | ((cmap_index[3] & bitmask)<<shift)>>3
  163.                             | ((cmap_index[4] & bitmask)<<shift)>>4
  164.                             | ((cmap_index[5] & bitmask)<<shift)>>5
  165.                             | ((cmap_index[6] & bitmask)<<shift)>>6
  166.                             | ((cmap_index[7] & bitmask)<<shift)>>7;
  167.  
  168.                     #ifdef GRAPHICS_SUPPORT_DEBUG
  169.                     printf("bitmask:%4.d   i:%d buffer:%d\n", bitmask, i, buffer);
  170.                     #endif
  171.                     *(bitmap->Planes[i]+offset)=buffer;
  172.                     bitmask=bitmask>>1;
  173.                     shift++;
  174.                 }
  175.             }
  176.             #ifdef GRAPHICS_SUPPORT_DEBUG
  177.             printf("\n\n");
  178.             #endif
  179.             offset++;
  180.         }
  181.     }
  182. }
  183.  
  184.  
  185. /*
  186. ** INPUTS:
  187. **          pens        = pointer to an array of pen numbers
  188. **          num_pens    = the size of the array (how many pens it can hold)
  189. **                        NB: max = 256
  190. **
  191. ** RESULT:
  192. **          The free pen index, or -1 on failure
  193. */
  194. WORD findfreepen (struct pen *pens, UWORD num_pens)
  195. {
  196.     UWORD i;
  197.  
  198.     for (i=0; i<num_pens; i++)
  199.     {
  200.         if (pens[i].number==-1)
  201.             return i;
  202.     }
  203.     return -1;  // if we get this far, there were no free pens
  204. }
  205.  
  206. /*
  207. ** INPUTS:
  208. **          R, G, B     = red, green and blue values (32 bit left justified fraction)
  209. **          pens        = pointer to an array of pen numbers
  210. **          num_pens    = the size of the array (how many pens it can hold)
  211. **                        NB: max = 256
  212. **
  213. ** RESULT:
  214. **          TRUE if we already have a suitable pen, FALSE otherwise
  215. */
  216. BOOL alreadyallocated (ULONG R, ULONG G, ULONG B, struct pen *pens, UWORD num_pens)
  217. {
  218.     UWORD i;
  219.  
  220.     for (i=0; i<num_pens; i++)
  221.     {
  222.         if (pens[i].red==R && pens[i].green==G && pens[i].blue==B)
  223.             return TRUE;
  224.     }
  225.     return FALSE;
  226. }
  227.  
  228.  
  229. /*
  230. ** INPUTS:
  231. **          R, G, B     = red, green and blue values (32 bit left justified fraction)
  232. **          pens        = pointer to an array of pen numbers
  233. **          num_pens    = the size of the array (how many pens it can hold)
  234. **                        NB: max = 256
  235. **
  236. ** RESULT:
  237. **          An index into our array of allocated pens, or -1 if no matching pen is found
  238. */
  239. WORD findallocatedpen (ULONG R, ULONG G, ULONG B, struct pen *pens, UWORD num_pens)
  240. {
  241.     UWORD i;
  242.  
  243.     for (i=0; i<num_pens; i++)
  244.     {
  245.         if (pens[i].red==R && pens[i].green==G && pens[i].blue==B && pens[i].number!=-1)
  246.             return i;
  247.     }
  248.     return -1;
  249. }
  250.  
  251. /*
  252. ** INPUTS:
  253. **          cm          = pointer to ColorMap of the viewport
  254. **          pens        = pointer to an array of pen numbers
  255. **          num_pens    = the size of the array (how many pens it can hold)
  256. **                        NB: max = 256
  257. **
  258. ** RESULT:
  259. **          None
  260. */
  261. void freeallocatedpens (struct ColorMap *cm, struct pen *pens, UWORD num_pens)
  262. {
  263.     UWORD i;
  264.  
  265.     for (i=0; i<num_pens; i++)
  266.     {
  267.         if (pens[i].number!=-1)
  268.             ReleasePen(cm, pens[i].number);
  269.         else
  270.             break;
  271.     }
  272. }
  273.  
  274. #ifdef GRAPHICS_SUPPORT_DEBUG
  275. void print_pens (struct pen *pens, UWORD num_pens)
  276. {
  277.     UWORD i;
  278.  
  279.     printf("Pens: ");
  280.     for (i=0; i<num_pens; i++)
  281.     {
  282.         if (pens[i].number!=-1)
  283.             printf("%3.d = R:%x G:%x B%x\n", pens[i].number, pens[i].red, pens[i].green, pens[i].blue);
  284.         else
  285.             break;
  286.     }
  287.     printf("\n");
  288. }
  289. #endif
  290.  
  291.  
  292. struct BitMap *bodytobitmap (ULONG width, ULONG height, ULONG depth, UBYTE *body)
  293. {
  294.     struct BitMap *bitmap;
  295.  
  296.     // Allocate 8 bitplanes so that the remapping routine has room to write
  297.     // back pen numbers from ObtainBestPen() with values up to 255
  298.     bitmap=AllocBitMap(width, height, 8, BMF_CLEAR | BMF_MINPLANES, NULL);
  299.  
  300.     {
  301.         char plane, scanline;
  302.         int row_width=((width+15)/16)*2;   // row width in bytes
  303.         UBYTE *body_rover;
  304.         int plane_offset=0;
  305.  
  306.         body_rover=body;
  307.  
  308.         for (scanline=0; scanline<height; scanline++)
  309.         {
  310.             for (plane=0; plane<depth; plane++)
  311.             {
  312.                 memcpy(bitmap->Planes[plane]+plane_offset, body_rover, row_width);
  313.                 body_rover+=row_width;
  314.             }
  315.             plane_offset=row_width*(scanline+1);
  316.         }
  317.     }
  318.  
  319.     return bitmap;
  320. }
  321.  
  322. BOOL loadiff (char *filename, ULONG *width, ULONG *height, ULONG *depth, ULONG *compression, UBYTE **body, ULONG **palette)
  323. {
  324.     struct IFFHandle *iff;
  325.     BOOL result=FALSE;
  326.  
  327.     if (iff=AllocIFF())
  328.     {
  329.         if (iff->iff_Stream=Open(filename, MODE_OLDFILE))
  330.         {
  331.             InitIFFasDOS(iff);
  332.  
  333.             if (!OpenIFF(iff, IFFF_READ))
  334.             {
  335.                 if (!PropChunk(iff, ID_ILBM, ID_BMHD))
  336.                 {
  337.                     if (!PropChunk(iff, ID_ILBM, ID_CMAP))
  338.                     {
  339.                         if (!StopChunk(iff, ID_ILBM, ID_BODY))
  340.                         {
  341.                             ParseIFF(iff, IFFPARSE_SCAN);
  342.  
  343.                             {
  344.                                 struct StoredProperty *bmhd;
  345.  
  346.                                 if (bmhd=FindProp(iff, ID_ILBM, ID_BMHD))
  347.                                 {
  348.                                     struct BitMapHeader *the_bmhd;
  349.  
  350.                                     the_bmhd=(struct BitMapHeader *)bmhd->sp_Data;
  351.                                     *width=the_bmhd->bmh_Width;
  352.                                     *height=the_bmhd->bmh_Height;
  353.                                     *depth=the_bmhd->bmh_Depth;
  354.  
  355.                                     // Don't store bmh_Compression value if compression==NULL
  356.                                     if (compression)
  357.                                         *compression=the_bmhd->bmh_Compression;
  358.                                 }
  359.                             }
  360.  
  361.                             {
  362.                                 struct StoredProperty *cmap;
  363.  
  364.                                 if (cmap=FindProp(iff, ID_ILBM, ID_CMAP))
  365.                                 {
  366.                                     int num_primary_colours=cmap->sp_Size;
  367.                                     UBYTE *primary_colour=cmap->sp_Data;
  368.                                     int i;
  369.  
  370.                                     *palette=(ULONG *)calloc(num_primary_colours, sizeof(ULONG));
  371.                                     memset(*palette, 0, sizeof(ULONG)*num_primary_colours);
  372.  
  373.                                     for (i=0; i<num_primary_colours; i++)
  374.                                     {
  375.                                         (*palette)[i]=*primary_colour++;
  376.                                         (*palette)[i]=(*palette)[i]<<24;
  377.                                     }
  378.                                 }
  379.                             }
  380.  
  381.                             {
  382.                                 struct ContextNode *cn;
  383.  
  384.                                 cn=CurrentChunk(iff);
  385.                                 *body=(UBYTE *)malloc(cn->cn_Size);
  386.                                 ReadChunkBytes(iff, *body, cn->cn_Size);
  387.                             }
  388.  
  389.                             result=TRUE;
  390.                         }
  391.                     }
  392.                 }
  393.                 CloseIFF(iff);
  394.             }
  395.             Close(iff->iff_Stream);
  396.         }
  397.         FreeIFF(iff);
  398.     }
  399.  
  400.     return result;
  401. }
  402.  
  403.  
  404.